package fr.pud.client.model;

import java.io.Serializable;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;

import org.openstreetmap.gui.jmapviewer.Coordinate;

import fr.pud.utils.Tools4PUDStation;

/**
 * A singleton which represents the database of PUDStation.
 * Apr 3, 2012 - OSE
 * @author Simon Devineau, Adrien Hierry, Leopold Houdin, Pierre Reliquet
 *         Ecole des Mines de Nantes
 *         PUDStationDatabase.java
 */
public class PUDStationDatabase extends Observable implements Serializable,
        Observer {
    public static PUDStation              NO_STATION       = null;
    /**
     * The serial ID to serialize the Class
     */
    private static final long             serialVersionUID = 8449866158225179454L;
    /**
     * The singleton
     */
    private static PUDStationDatabase     instance         = null;
    /**
     * The set of PUDStation which represent the implementation of our database.
     */
    private static Collection<PUDStation> stations         = Tools4PUDStation
                                                                   .loadPUDSationsData();

    /**
     * @return the instance
     */
    public static PUDStationDatabase getInstance() {
        initialize();
        return instance;
    }

    /**
     * Initiate if the instance is equal to null
     */
    private static void initialize() {
        if (instance == null) {
            instance = new PUDStationDatabase();
        }
    }

    /**
     * The default constructor
     */
    public PUDStationDatabase() {
        stations = Tools4PUDStation.loadPUDSationsData();
    }

    /**
     * @param aStation
     *            the station to add
     * @return true if the station has been added
     */
    public boolean addStation(PUDStation aStation) {
        return stations.add(aStation);
    }

    /**
     * 
     */
    public PUDStation getStation(Coordinate c) {
        for (PUDStation station : stations) {
            if (c.equals(station.getAddress().getCoordinate())) {
                return station;
            }
        }
        return NO_STATION;
    }

    /**
     * @return the database as a Set<PUDStation>.
     */
    public Collection<PUDStation> getStations() {
        initialize();
        return stations;
    }

    /**
     * @param aStations
     *            the stations to set
     */
    public void setStations(Set<PUDStation> aStations) {
        initialize();
        stations = aStations;
    }

    /**
     * @return an array representation of the database
     */
    public PUDStation[] toArray() {
        initialize();
        this.update(Queries.getInstance(), Queries.getInstance());
        PUDStation[] array = new PUDStation[stations.size()];
        int i = 0;
        for (PUDStation current : stations) {
            array[i++] = current;
        }
        return array;
    }

    @Override
    public void update(Observable aArg0, Object aArg1) {
        if (aArg1 instanceof Address) {
            stations.add(new PUDStation((Address) aArg1));
        }
        if (aArg0 instanceof Queries) {
            for (Query q : Queries.getInstance()) {
                stations.add(q.getDelivery());
                stations.add(q.getPickup());
                this.setChanged();
                this.notifyObservers();
            }
        }
    }
}
